//函数类型的接口

//普通函数
//声明函数的两种方式：
//1、function fun(a,b){ console.log( a+b ) }
//2、let fun = function(){}

function fun7(x: string, y: number): string {
    return x + y
}


//一、日常简写方式
let funn2 = function (x: string, y: number): string {
    return x + y
}
console.log(funn2('1', 2))

//二、在ts当中完整的写法
//在函数当中规定数据类型，主要是两个：1、形参的类型声明；2、函数返回值的类型声明。
//注意：在函数中，函数也是要类型声明的，只是我们平常写成了简写方式，因为ts的类型推断，所以不会报错。
//          形参的类型声明            函数返回值的类型声明
let funn1: (a: string, b: string) => string = function (x: string, y: string): string {
    return x + y
}
console.log(funn1('a', 'b'))

//函数的参数，有很多情况
//(1) ?  有的参数，可有可无。
//注意：虽然设有?的参数可传可不传，传不传都不会报错，但是不传，会默认传进一个undefined
let funn3: (x: string, y: number, z?: string) => string = function (x: string, y: number, z?: string): string {
    return x + y + z
}
console.log(funn3('1', 2))  // 12undefined  虽然第三个参数z，可传可不传，但是不传的时候，会默认传进一个 undefined

//不报错  但是不建议
let funn4: (x: string, y: number, z?: string) => string = function (a: string, b: number): string {
    return a + b
}
console.log(funn4('1', 2)) // 12

//(2)函数有形参默认值
//形参默认值：有参数传入，就是传入的值；无值传入，就是默认值。
function funn5(x:string,y:number,sex:string='女'):string{
    return x+y+sex
}
console.log(funn5('tony',18,'男'))
console.log(funn5('marry',20))

//(3)有可能函数有很多参数传入，但是我现在不知道有哪些。
//解析：args:string[] 代表 一个名叫args，且元素都为字符串的数组，在这里，代表剩余实参的集合
//解析：...args:string[] 将数组展开   注意：展开的元素，有逗号隔开
function funn6(x:string,y:number,...args:string[]):string{
    return x+y+args
}
console.log(funn6('tom',20,'打球','打字第一名','小甜甜'))//tom20打球,打字第一名,小甜甜   注意：有逗号隔开

//三、函数调用签名(函数的接口)
//(1)设置函数接口
interface Fun{
    (x:string,y:number,z?:unknown):string
}
//(2)使用函数接口
let funn7:Fun = function(a:string,b:number,c?:unknown):string{
    return a+b+c
}
console.log(funn7('tom',20))   //tom20undefined
console.log(funn7('1',2,3)) //123

let funn8:Fun = function(x:string,y:number,z?:unknown){
    return x+y+z
}
console.log(funn8('marry',18,'学习'))//marry18学习

//函数调用签名
export {
        fun7
    }